﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mimoza.Transport;

namespace Mimoza.DBLayer.Transport.Server
{
    public class CollectionManager :
        ICollectionRequestProcessor
    {
        public CollectionManager()
        {
            CollectionRequest.RegisterHandler(ProcessRequest);
        }

        public void AddCollection(ICollection collection, Connection conn)
        {
            lock (m_collections)
            {
                m_collections[collection.CollectionID] = new CollectionItem(collection, conn);
                conn.CloseHandler += OnConnectionClose;
            }
        }

        public void DeleteCollection(Guid collectionId)
        {
            lock (m_collections)
            {
                if (m_collections.ContainsKey(collectionId))
                {
                    m_collections.Remove(collectionId);

                }
            }
        }

        void OnConnectionClose(Connection conn)
        {
            ICollection foundConn = null;
            lock (m_collections)
            {
                foreach (KeyValuePair<Guid, CollectionItem> pair in m_collections)
                {
                    if (pair.Value.Connection == conn)
                    {
                        foundConn = pair.Value.Collection;
                        DeleteCollection(pair.Key);
                        break;
                    }
                }
            }

            if (foundConn != null)
            {
                foundConn.Dispose();
            }
        }

        CollectionItem FindCollection(Guid collectionId)
        {
            CollectionItem result = null;
            lock (m_collections)
            {
                if (!m_collections.ContainsKey(collectionId))
                {
                    throw new ArgumentException();
                }

                result = m_collections[collectionId];
            }
            return result;
        }

        public TransferObject ProcessRequest(CollectionRequest request)
        {
            CollectionItem collectionItem = FindCollection(request.CollectionTransfer.ID);            

            TransferObject result = null;
            switch (request.CollectionTransfer.OperationType)
            {
                case CollectionTransfer.Operation.Reset:
                    result = collectionItem.Collection.Reset();
                    break;
                case CollectionTransfer.Operation.MoveNext:
                    result = collectionItem.Collection.MoveNext();
                    break;
                case CollectionTransfer.Operation.Current:
                    result = collectionItem.Collection.Current;
                    break;
                case CollectionTransfer.Operation.Dispose:
                    result = collectionItem.Collection.Dispose();
                    DeleteCollection(request.CollectionTransfer.ID);
                    break;
            }

            return result;
        }


        class CollectionItem
        {
            public CollectionItem()
            {
            }
            public CollectionItem(ICollection collection, Connection connection)
            {
                Collection = collection;
                Connection = connection;
            }

            public ICollection Collection;
            public Connection Connection;
        };

        Dictionary<Guid, CollectionItem> m_collections = new Dictionary<Guid,CollectionItem>();
    }
}
